from flask import request, jsonify, g
from flask_jwt_extended import jwt_required, get_jwt_identity
import datetime
from bson import ObjectId

from app.api.v1 import api_bp
from app import mongo
from app.utils.auth import permission_required
from app.utils.common import normalize_data, paginate, generate_id
from app.schemas.appointment import AppointmentSchema, AppointmentUpdateSchema

# 添加一个工具函数，将日期字符串或date对象转换为datetime对象
def convert_to_datetime(date_value):
    """将日期值转换为datetime对象，以便MongoDB可以正确处理"""
    if isinstance(date_value, str):
        # 将字符串转换为datetime对象
        return datetime.datetime.strptime(date_value, '%Y-%m-%d')
    elif isinstance(date_value, datetime.date) and not isinstance(date_value, datetime.datetime):
        # 将date对象转换为datetime对象
        return datetime.datetime.combine(date_value, datetime.time.min)
    return date_value

@api_bp.route('/appointments', methods=['GET'])
@jwt_required()
@permission_required('appointment:read')
def get_appointments():
    """获取预约列表"""
    page = request.args.get('page', 1, type=int)
    limit = request.args.get('limit', 20, type=int)
    sort_by = request.args.get('sortBy', 'appointmentDate')
    order = request.args.get('order', 'desc')
    
    # 构建查询条件
    query = {}
    
    # 按患者ID筛选
    patient_id = request.args.get('patientId')
    if patient_id:
        query['patientId'] = patient_id
    
    # 按医生ID筛选
    doctor_id = request.args.get('doctorId')
    if doctor_id:
        query['doctorId'] = doctor_id
    
    # 按科室ID筛选
    department_id = request.args.get('departmentId')
    if department_id:
        query['departmentId'] = department_id
    
    # 按状态筛选
    status = request.args.get('status')
    if status and status != 'all':
        query['status'] = status
    
    # 按支付状态筛选
    payment_status = request.args.get('paymentStatus')
    if payment_status and payment_status != 'all':
        query['paymentStatus'] = payment_status
    
    # 按日期范围筛选
    start_date = request.args.get('startDate')
    if start_date:
        try:
            # 修改这里：使用convert_to_datetime处理日期
            start_date = convert_to_datetime(start_date)
            if 'appointmentDate' not in query:
                query['appointmentDate'] = {}
            query['appointmentDate']['$gte'] = start_date
        except ValueError:
            pass
    
    end_date = request.args.get('endDate')
    if end_date:
        try:
            # 修改这里：使用convert_to_datetime处理日期
            end_date = convert_to_datetime(end_date)
            if 'appointmentDate' not in query:
                query['appointmentDate'] = {}
            query['appointmentDate']['$lte'] = end_date
        except ValueError:
            pass
    
    # 确定排序
    sort_direction = -1 if order.lower() == 'desc' else 1
    
    # 获取数据
    appointments_cursor = mongo.db.appointments.find(query).sort(sort_by, sort_direction)
    
    # 分页
    paginated_data = paginate(appointments_cursor, page, limit)
    
    # 标准化数据并添加患者和医生信息
    appointments = []
    for appointment in paginated_data['items']:
        normalized_appointment = normalize_data(appointment)
        
        # 获取患者信息
        patient_name = ''
        if 'patientId' in appointment:
            patient_id = appointment['patientId']
            if isinstance(patient_id, str) and ObjectId.is_valid(patient_id):
                patient_id = ObjectId(patient_id)
            patient = mongo.db.patients.find_one({'_id': patient_id})
            if patient:
                patient_name = patient.get('name', '')
        normalized_appointment['patientName'] = patient_name
        
        # 获取医生信息
        doctor_name = ''
        if 'doctorId' in appointment:
            doctor_id = appointment['doctorId']
            if isinstance(doctor_id, str) and ObjectId.is_valid(doctor_id):
                doctor_id = ObjectId(doctor_id)
            doctor = mongo.db.doctors.find_one({'_id': doctor_id})
            if doctor:
                doctor_name = doctor.get('name', '')
        normalized_appointment['doctorName'] = doctor_name
        
        # 获取科室信息
        department_name = ''
        if 'departmentId' in appointment:
            dept_id = appointment['departmentId']
            if isinstance(dept_id, str) and ObjectId.is_valid(dept_id):
                dept_id = ObjectId(dept_id)
            department = mongo.db.departments.find_one({'_id': dept_id})
            if department:
                department_name = department.get('name', '')
        normalized_appointment['departmentName'] = department_name
        
        # 明确显示预约状态信息
        current_status = appointment.get('status', '')
        payment_status = appointment.get('paymentStatus', '未支付')
        
        # 简化的状态信息
        normalized_appointment['appointmentStatus'] = current_status
        normalized_appointment['paymentStatus'] = payment_status
        
        appointments.append(normalized_appointment)
    
    return jsonify({
        'success': True,
        'data': {
            'total': paginated_data['total'],
            'page': paginated_data['page'],
            'limit': paginated_data['per_page'],
            'appointments': appointments
        }
    }), 200

@api_bp.route('/appointments', methods=['POST'])
@jwt_required()
@permission_required('appointment:create')
def create_appointment():
    """创建新预约"""
    # 验证请求数据
    schema = AppointmentSchema()
    errors = schema.validate(request.json)
    if errors:
        return jsonify({
            'success': False,
            'message': '请求数据验证失败',
            'errors': errors
        }), 400
    
    data = request.json
    
    # 验证患者是否存在
    patient_id = data.get('patientId')
    if not mongo.db.patients.find_one({'_id': ObjectId(patient_id)}):
        return jsonify({
            'success': False,
            'message': '患者不存在'
        }), 400
    
    # 验证排班是否存在
    schedule_id = data.get('scheduleId')
    if not ObjectId.is_valid(schedule_id):
        return jsonify({
            'success': False,
            'message': '排班ID无效'
        }), 400
    
    schedule = mongo.db.schedules.find_one({'_id': ObjectId(schedule_id)})
    if not schedule:
        return jsonify({
            'success': False,
            'message': '排班不存在'
        }), 400
    
    # 验证医生和科室是否与排班一致
    doctor_id = data.get('doctorId')
    if doctor_id != schedule.get('doctorId'):
        return jsonify({
            'success': False,
            'message': '医生ID与排班不匹配'
        }), 400
    
    department_id = data.get('departmentId')
    if department_id != schedule.get('departmentId'):
        return jsonify({
            'success': False,
            'message': '科室ID与排班不匹配'
        }), 400
    
    # 验证预约日期是否与排班日期一致
    appointment_date = data.get('appointmentDate')
    if isinstance(appointment_date, str):
        try:
            # 修改这里：使用convert_to_datetime处理日期
            appointment_date = convert_to_datetime(appointment_date)
        except ValueError:
            return jsonify({
                'success': False,
                'message': '预约日期格式无效'
            }), 400
    
    # 更新data中的appointmentDate为datetime对象
    data['appointmentDate'] = appointment_date
    
    schedule_date = schedule.get('date')
    if isinstance(schedule_date, datetime.datetime):
        schedule_date = schedule_date.date()
    elif isinstance(schedule_date, str):
        schedule_date = datetime.datetime.strptime(schedule_date, '%Y-%m-%d').date()
    
    # 将日期对象转换为datetime对象进行比较
    if appointment_date.date() != schedule_date:
        return jsonify({
            'success': False,
            'message': '预约日期与排班日期不匹配'
        }), 400
    
    # 验证预约时段
    period = data.get('period')
    time_slot = data.get('timeSlot')
    
    # 检查该时段是否还有剩余容量
    remaining_capacity = schedule.get('remainingCapacity', {})
    if period not in remaining_capacity or remaining_capacity[period] <= 0:
        return jsonify({
            'success': False,
            'message': f'该时段({period})已约满'
        }), 400
    
    # 检查该患者是否已有同日期同科室的预约
    existing_appointment = mongo.db.appointments.find_one({
        'patientId': patient_id,
        'departmentId': department_id,
        'appointmentDate': appointment_date,  # 这里使用datetime对象
        'status': {'$in': ['预约中', '已到诊']}
    })
    
    if existing_appointment:
        return jsonify({
            'success': False,
            'message': '该患者已有同日期同科室的预约'
        }), 400
    
    # 获取挂号费用
    data['registrationFee'] = schedule.get('registrationFee', 0.0)
    
    # 生成预约号
    data['appointmentId'] = generate_id('AP')
    
    # 设置创建时间和更新时间
    now = datetime.datetime.utcnow()
    data['createdAt'] = now
    data['updatedAt'] = now
    
    # 确保添加状态字段
    if 'status' not in data:
        data['status'] = '预约中'
    
    # 确保添加支付状态字段
    if 'paymentStatus' not in data:
        data['paymentStatus'] = '未支付'
    
    # 保存到数据库
    result = mongo.db.appointments.insert_one(data)
    
    # 更新排班剩余容量
    mongo.db.schedules.update_one(
        {'_id': ObjectId(schedule_id)},
        {'$inc': {f'remainingCapacity.{period}': -1}}
    )
    
    # 如果剩余容量为0，检查是否需要将排班标记为已满
    updated_schedule = mongo.db.schedules.find_one({'_id': ObjectId(schedule_id)})
    remaining = updated_schedule.get('remainingCapacity', {})
    all_full = True
    for _, count in remaining.items():
        if count > 0:
            all_full = False
            break
    
    if all_full:
        mongo.db.schedules.update_one(
            {'_id': ObjectId(schedule_id)},
            {'$set': {'status': '已满', 'updatedAt': now}}
        )
    
    # 获取相关信息用于返回
    patient = mongo.db.patients.find_one({'_id': ObjectId(patient_id)})
    patient_name = patient.get('name', '') if patient else ''
    
    doctor = mongo.db.doctors.find_one({'_id': ObjectId(doctor_id)})
    doctor_name = doctor.get('name', '') if doctor else ''
    
    return jsonify({
        'success': True,
        'message': '预约创建成功',
        'data': {
            'id': str(result.inserted_id),
            'appointmentId': data['appointmentId'],
            'patientName': patient_name,
            'doctorName': doctor_name,
            'appointmentDate': appointment_date.isoformat(),
            'period': period,
            'timeSlot': time_slot,
            'status': data.get('status', '预约中'),
            'createdAt': now.isoformat()
        }
    }), 201

@api_bp.route('/appointments/<id>', methods=['GET'])
@jwt_required()
@permission_required('appointment:read')
def get_appointment(id):
    """获取单个预约详情"""
    # 尝试按ID查找
    appointment = None
    
    # 如果是有效的ObjectId，按_id查找
    if ObjectId.is_valid(id):
        appointment = mongo.db.appointments.find_one({'_id': ObjectId(id)})
    
    # 如果没找到，尝试按appointmentId查找
    if not appointment:
        appointment = mongo.db.appointments.find_one({'appointmentId': id})
    
    if not appointment:
        return jsonify({
            'success': False,
            'message': '预约不存在'
        }), 404
    
    # 标准化数据
    normalized_appointment = normalize_data(appointment)
    
    # 获取患者信息
    patient_info = None
    if 'patientId' in appointment:
        patient_id = appointment['patientId']
        if isinstance(patient_id, str) and ObjectId.is_valid(patient_id):
            patient_id = ObjectId(patient_id)
        patient = mongo.db.patients.find_one({'_id': patient_id})
        if patient:
            patient_info = {
                'id': str(patient['_id']),
                'patientId': patient.get('patientId', ''),
                'name': patient.get('name', ''),
                'gender': patient.get('gender', ''),
                'age': calculate_age(patient.get('birthDate')),
                'phone': patient.get('contactInfo', {}).get('phone', '')
            }
    normalized_appointment['patientInfo'] = patient_info
    
    # 获取医生信息
    doctor_info = None
    if 'doctorId' in appointment:
        doctor_id = appointment['doctorId']
        if isinstance(doctor_id, str) and ObjectId.is_valid(doctor_id):
            doctor_id = ObjectId(doctor_id)
        doctor = mongo.db.doctors.find_one({'_id': doctor_id})
        if doctor:
            doctor_info = {
                'id': str(doctor['_id']),
                'staffId': doctor.get('staffId', ''),
                'name': doctor.get('name', ''),
                'title': doctor.get('title', '')
            }
    normalized_appointment['doctorInfo'] = doctor_info
    
    # 获取科室信息
    department_info = None
    if 'departmentId' in appointment:
        dept_id = appointment['departmentId']
        if isinstance(dept_id, str) and ObjectId.is_valid(dept_id):
            dept_id = ObjectId(dept_id)
        department = mongo.db.departments.find_one({'_id': dept_id})
        if department:
            department_info = {
                'id': str(department['_id']),
                'code': department.get('code', ''),
                'name': department.get('name', ''),
                'location': department.get('location', '')
            }
    normalized_appointment['departmentInfo'] = department_info
    
    # 获取排班信息
    schedule_info = None
    if 'scheduleId' in appointment:
        sched_id = appointment['scheduleId']
        if isinstance(sched_id, str) and ObjectId.is_valid(sched_id):
            sched_id = ObjectId(sched_id)
        schedule = mongo.db.schedules.find_one({'_id': sched_id})
        if schedule:
            time_slots = schedule.get('timeSlots', [])
            period_slots = {}
            for slot in time_slots:
                period = slot.get('period')
                if period:
                    period_slots[period] = {
                        'startTime': slot.get('startTime'),
                        'endTime': slot.get('endTime')
                    }
            
            schedule_info = {
                'id': str(schedule['_id']),
                'room': schedule.get('room', ''),
                'timeSlots': period_slots
            }
    normalized_appointment['scheduleInfo'] = schedule_info
    
    # 获取预约日期
    appointment_date = appointment.get('appointmentDate')
    # 确保这里返回的是字符串格式的日期
    if appointment_date:
        if isinstance(appointment_date, (datetime.datetime, datetime.date)):
            normalized_appointment['appointmentDate'] = appointment_date.strftime('%Y-%m-%d')
    
    # 明确显示预约状态信息
    current_status = appointment.get('status', '')
    payment_status = appointment.get('paymentStatus', '未支付')
    
    # 简化的状态信息
    normalized_appointment['appointmentStatus'] = current_status
    normalized_appointment['paymentStatus'] = payment_status
    
    return jsonify({
        'success': True,
        'data': normalized_appointment
    }), 200

@api_bp.route('/appointments/<id>', methods=['PUT'])
@jwt_required()
@permission_required('appointment:update')
def update_appointment(id):
    """更新预约信息"""
    # 验证请求数据
    schema = AppointmentUpdateSchema()
    errors = schema.validate(request.json)
    if errors:
        return jsonify({
            'success': False,
            'message': '请求数据验证失败',
            'errors': errors
        }), 400
    
    data = request.json
    
    # 尝试按ID查找
    appointment = None
    if ObjectId.is_valid(id):
        appointment = mongo.db.appointments.find_one({'_id': ObjectId(id)})
    
    if not appointment:
        appointment = mongo.db.appointments.find_one({'appointmentId': id})
    
    if not appointment:
        return jsonify({
            'success': False,
            'message': '预约不存在'
        }), 404
    
    # 不允许修改已取消的预约
    if appointment.get('status') == '已取消':
        return jsonify({
            'success': False,
            'message': '已取消的预约不能修改'
        }), 400
    
    # 如果状态从"预约中"变为"已取消"，需要恢复排班剩余容量
    if 'status' in data and data['status'] == '已取消' and appointment.get('status') != '已取消':
        schedule_id = appointment.get('scheduleId')
        period = appointment.get('period')
        
        # 更新排班剩余容量
        if schedule_id and period and ObjectId.is_valid(schedule_id):
            mongo.db.schedules.update_one(
                {'_id': ObjectId(schedule_id)},
                {'$inc': {f'remainingCapacity.{period}': 1}}
            )
            
            # 更新排班状态
            mongo.db.schedules.update_one(
                {'_id': ObjectId(schedule_id), 'status': '已满'},
                {'$set': {'status': '正常', 'updatedAt': datetime.datetime.utcnow()}}
            )
    
    # 准备更新数据
    update_data = data.copy()
    update_data['updatedAt'] = datetime.datetime.utcnow()
    
    # 更新数据库
    result = mongo.db.appointments.update_one(
        {'_id': appointment['_id']},
        {'$set': update_data}
    )
    
    if result.modified_count == 0:
        return jsonify({
            'success': False,
            'message': '预约更新失败'
        }), 500
    
    return jsonify({
        'success': True,
        'message': '预约更新成功',
        'data': {
            'id': str(appointment['_id']),
            'appointmentId': appointment.get('appointmentId', ''),
            'status': data.get('status', appointment.get('status')),
            'updatedAt': update_data['updatedAt'].isoformat()
        }
    }), 200

@api_bp.route('/appointments/<id>/cancel', methods=['POST'])
@jwt_required()
@permission_required('appointment:update')
def cancel_appointment(id):
    """取消预约"""
    try:
        # 验证ID是否有效
        if not ObjectId.is_valid(id):
            return jsonify({
                'success': False,
                'message': '无效的预约ID'
            }), 400
        
        # 查找预约
        appointment = mongo.db.appointments.find_one({'_id': ObjectId(id)})
        
        if not appointment:
            return jsonify({
                'success': False,
                'message': '预约不存在'
            }), 404
        
        # 检查预约是否可以取消
        if appointment.get('status') not in ['预约中']:
            return jsonify({
                'success': False,
                'message': '只有"预约中"状态的预约可以取消'
            }), 400
        
        # 检查是否是患者本人或有权限的用户
        current_user_id = get_jwt_identity()
        user = mongo.db.users.find_one({'_id': ObjectId(current_user_id)})
        
        can_cancel = False
        # 系统管理员、前台或者有appointment:update权限的用户
        if user and (
            user.get('role') == 'admin' or 
            user.get('role') == 'receptionist' or 
            (hasattr(g, 'user_permissions') and 'appointment:update' in g.user_permissions)
        ):
            can_cancel = True
        # 患者本人（通过关联的用户ID匹配）
        elif user and user.get('role') == 'patient':
            patient = mongo.db.patients.find_one({'_id': ObjectId(appointment.get('patientId', ''))})
            if patient:
                # 统一转为字符串进行比较
                patient_user_id = str(patient.get('userId', ''))
                current_user_id_str = str(current_user_id)
                if patient_user_id == current_user_id_str:
                    can_cancel = True
        
        if not can_cancel:
            return jsonify({
                'success': False,
                'message': '没有权限取消该预约',
                'error': 'permission_denied'
            }), 403
        
        # 获取预约日期和当前日期以检查是否可以取消
        appointment_date = appointment.get('appointmentDate')
        # 确保appointment_date是datetime对象
        if isinstance(appointment_date, str):
            try:
                appointment_date = convert_to_datetime(appointment_date)
            except Exception as e:
                return jsonify({
                    'success': False,
                    'message': f'预约日期格式无效: {str(e)}'
                }), 400
        elif isinstance(appointment_date, datetime.date) and not isinstance(appointment_date, datetime.datetime):
            appointment_date = convert_to_datetime(appointment_date)
        
        current_date = datetime.datetime.now()
        
        # 预约日期和当前日期的差距小于24小时则不允许取消
        try:
            time_diff = (appointment_date - current_date).total_seconds()
            if time_diff < 24 * 3600:
                return jsonify({
                    'success': False,
                    'message': '预约时间不足24小时，无法取消'
                }), 400
        except Exception as e:
            return jsonify({
                'success': False,
                'message': f'日期比较错误: {str(e)}'
            }), 400
        
        # 获取备注信息
        remarks = request.json.get('remarks', '')
        
        # 更新预约状态
        now = datetime.datetime.utcnow()
        update_result = mongo.db.appointments.update_one(
            {'_id': ObjectId(id)},
            {
                '$set': {
                    'status': '已取消',
                    'remarks': remarks,
                    'updatedAt': now
                }
            }
        )
        
        if update_result.modified_count == 0:
            return jsonify({
                'success': False,
                'message': '预约取消失败'
            }), 500
        
        # 恢复排班的剩余容量
        schedule_id = appointment.get('scheduleId')
        period = appointment.get('period')
        
        if schedule_id and period:
            try:
                mongo.db.schedules.update_one(
                    {'_id': ObjectId(schedule_id)},
                    {
                        '$inc': {f'remainingCapacity.{period}': 1},
                        '$set': {'status': '正常', 'updatedAt': now}
                    }
                )
            except Exception as e:
                # 记录错误但不影响取消操作
                print(f"更新排班容量时出错: {str(e)}")
        
        return jsonify({
            'success': True,
            'message': '预约已成功取消',
            'data': None
        }), 200
    
    except Exception as e:
        # 捕获所有未处理的异常
        print(f"取消预约时发生错误: {str(e)}")
        return jsonify({
            'success': False,
            'message': f'服务器内部错误: {str(e)}',
            'error': 'server_error'
        }), 500

@api_bp.route('/appointments/<id>/checkin', methods=['POST'])
@jwt_required()
@permission_required('appointment:checkin')
def checkin_appointment(id):
    """预约签到"""
    # 验证ID是否有效
    if not ObjectId.is_valid(id):
        return jsonify({
            'success': False,
            'message': '无效的预约ID'
        }), 400
    
    # 查找预约
    appointment = mongo.db.appointments.find_one({'_id': ObjectId(id)})
    
    if not appointment:
        return jsonify({
            'success': False,
            'message': '预约不存在'
        }), 404
    
    # 检查预约是否可以签到
    if appointment.get('status') != '预约中':
        return jsonify({
            'success': False,
            'message': '只有"预约中"状态的预约可以签到'
        }), 400
    
    # 检查预约日期是否为当天
    appointment_date = appointment.get('appointmentDate')
    # 确保appointment_date是datetime对象
    if isinstance(appointment_date, str):
        appointment_date = convert_to_datetime(appointment_date)
    elif isinstance(appointment_date, datetime.date) and not isinstance(appointment_date, datetime.datetime):
        appointment_date = convert_to_datetime(appointment_date)
    
    current_date = datetime.datetime.now().date()
    
    if appointment_date.date() != current_date:
        return jsonify({
            'success': False,
            'message': '只能为当天的预约签到'
        }), 400
    
    # 更新预约状态
    now = datetime.datetime.utcnow()
    update_result = mongo.db.appointments.update_one(
        {'_id': ObjectId(id)},
        {
            '$set': {
                'status': '已到诊',
                'checkinTime': now,
                'updatedAt': now
            }
        }
    )
    
    if update_result.modified_count == 0:
        return jsonify({
            'success': False,
            'message': '预约签到失败'
        }), 500
    
    # 获取患者信息
    patient_id = appointment.get('patientId')
    patient = None
    if patient_id:
        patient = mongo.db.patients.find_one({'_id': ObjectId(patient_id)})
    
    # 获取医生信息
    doctor_id = appointment.get('doctorId')
    doctor = None
    if doctor_id:
        doctor = mongo.db.doctors.find_one({'_id': ObjectId(doctor_id)})
    
    # 获取科室信息
    department_id = appointment.get('departmentId')
    department = None
    if department_id:
        department = mongo.db.departments.find_one({'_id': ObjectId(department_id)})
    
    return jsonify({
        'success': True,
        'message': '预约签到成功',
        'data': {
            'id': id,
            'appointmentId': appointment.get('appointmentId', ''),
            'patientName': patient.get('name', '') if patient else '',
            'doctorName': doctor.get('name', '') if doctor else '',
            'departmentName': department.get('name', '') if department else '',
            'checkinTime': now.isoformat()
        }
    }), 200

@api_bp.route('/appointments/<id>/payment', methods=['POST'])
@jwt_required()
@permission_required('appointment:payment')
def update_payment_status(id):
    """更新预约支付状态"""
    # 获取请求数据
    data = request.json
    payment_status = data.get('paymentStatus')
    
    if not payment_status:
        return jsonify({
            'success': False,
            'message': '支付状态不能为空'
        }), 400
    
    if payment_status not in ['未支付', '已支付', '已退款']:
        return jsonify({
            'success': False,
            'message': '无效的支付状态'
        }), 400
    
    # 尝试按ID查找
    appointment = None
    if ObjectId.is_valid(id):
        appointment = mongo.db.appointments.find_one({'_id': ObjectId(id)})
    
    if not appointment:
        appointment = mongo.db.appointments.find_one({'appointmentId': id})
    
    if not appointment:
        return jsonify({
            'success': False,
            'message': '预约不存在'
        }), 404
    
    # 不允许更新已取消预约的支付状态（除非是退款）
    if appointment.get('status') == '已取消' and payment_status != '已退款':
        return jsonify({
            'success': False,
            'message': '已取消的预约只能设置为已退款状态'
        }), 400
    
    # 准备更新数据
    now = datetime.datetime.utcnow()
    update_data = {
        'paymentStatus': payment_status,
        'updatedAt': now
    }
    
    # 添加支付时间或退款时间
    if payment_status == '已支付':
        update_data['paymentTime'] = now
    elif payment_status == '已退款':
        update_data['refundTime'] = now
    
    # 如果有支付方式
    payment_method = data.get('paymentMethod')
    if payment_method:
        update_data['paymentMethod'] = payment_method
    
    # 如果有交易号
    transaction_id = data.get('transactionId')
    if transaction_id:
        update_data['transactionId'] = transaction_id
    
    # 如果有备注信息
    remarks = data.get('remarks')
    if remarks:
        update_data['paymentRemarks'] = remarks
    
    # 更新数据库
    result = mongo.db.appointments.update_one(
        {'_id': appointment['_id']},
        {'$set': update_data}
    )
    
    if result.modified_count == 0:
        return jsonify({
            'success': False,
            'message': '支付状态更新失败'
        }), 500
    
    # 集成到支付系统：当状态设置为已支付时，创建支付记录
    if payment_status == '已支付':
        try:
            # 获取患者ID
            patient_id = appointment.get('patientId')
            
            # 获取挂号费
            registration_fee = appointment.get('registrationFee', 0)
            
            # 创建支付记录
            payment_data = {
                'paymentId': generate_id('P'),
                'patientId': patient_id,
                'amount': registration_fee,
                'totalAmount': registration_fee,
                'paymentMethod': payment_method or '其他',
                'status': '成功',
                'items': [
                    {
                        'type': 'registration',
                        'itemId': str(appointment['_id']),
                        'amount': registration_fee
                    }
                ],
                'transactionId': transaction_id,
                'createdAt': now,
                'updatedAt': now,
                'paidAt': now
            }
            
            # 如果有部门信息，添加departmentId
            if 'departmentId' in appointment:
                payment_data['departmentId'] = appointment.get('departmentId')
            
            # 保存支付记录
            payment_result = mongo.db.payments.insert_one(payment_data)
            
            # 更新预约中的支付记录ID
            mongo.db.appointments.update_one(
                {'_id': appointment['_id']},
                {'$set': {'paymentId': str(payment_result.inserted_id)}}
            )
        except Exception as e:
            # 记录错误但不影响预约状态更新
            print(f"创建支付记录时出错: {str(e)}")
    
    # 如果是退款，创建退款记录
    elif payment_status == '已退款' and appointment.get('paymentStatus') == '已支付':
        try:
            # 获取患者ID
            patient_id = appointment.get('patientId')
            
            # 获取挂号费
            registration_fee = appointment.get('registrationFee', 0)
            
            # 创建退款记录
            refund_data = {
                'paymentId': generate_id('R'),
                'patientId': patient_id,
                'amount': -registration_fee,  # 负数表示退款
                'totalAmount': -registration_fee,
                'paymentMethod': payment_method or appointment.get('paymentMethod', '其他'),
                'status': '成功',
                'items': [
                    {
                        'type': 'registration',
                        'itemId': str(appointment['_id']),
                        'amount': -registration_fee
                    }
                ],
                'transactionId': transaction_id,
                'createdAt': now,
                'updatedAt': now,
                'paidAt': now,
                'isRefund': True,
                'refundReason': remarks or '预约退款'
            }
            
            # 如果有部门信息，添加departmentId
            if 'departmentId' in appointment:
                refund_data['departmentId'] = appointment.get('departmentId')
            
            # 保存退款记录
            mongo.db.payments.insert_one(refund_data)
        except Exception as e:
            # 记录错误但不影响预约状态更新
            print(f"创建退款记录时出错: {str(e)}")
    
    return jsonify({
        'success': True,
        'message': f'支付状态已更新为"{payment_status}"',
        'data': {
            'id': str(appointment['_id']),
            'appointmentId': appointment.get('appointmentId', ''),
            'paymentStatus': payment_status,
            'updatedAt': now.isoformat()
        }
    }), 200

def calculate_age(birth_date):
    """计算年龄"""
    if not birth_date:
        return None
    
    if isinstance(birth_date, str):
        try:
            birth_date = datetime.datetime.strptime(birth_date, '%Y-%m-%d')
        except ValueError:
            return None
    
    today = datetime.date.today()
    age = today.year - birth_date.year - ((today.month, today.day) < (birth_date.month, birth_date.day))
    return age 